#include "tm1640.h"
#include "delay.h"
#include "UART.h"
const u8 tm1640_addr[] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF};

static void i2c_gpio_config(void)
{
    GPIO_InitTypeDef __xdata GPIO_InitStructure;                    //结构定义
    GPIO_InitStructure.Pin = I2C1_SDA_GPIO_PIN;              //指定要初始化的IO,
    GPIO_InitStructure.Mode = GPIO_OUT_OD;                  //指定IO的输入或输出方式
    GPIO_Inilize(I2C1_SDA_GPIO_PORT, &GPIO_InitStructure);   //初始化
    GPIO_InitStructure.Pin = I2C1_SCK_GPIO_PIN;              //指定要初始化的IO,
    GPIO_InitStructure.Mode = GPIO_OUT_OD;                  //指定IO的输入或输出方式
    GPIO_Inilize(I2C1_SCK_GPIO_PORT, &GPIO_InitStructure);   //初始化
    I2C1_SCK_HIGH();
    I2C1_SDA_HIGH();
}

static void i2c_start(void)
{
    I2C1_SCK_HIGH();
    I2C1_SDA_HIGH();
    delay_us(2);
    I2C1_SDA_LOW();
    delay_us(2);
    I2C1_SCK_LOW();
    delay_us(2);
}

static void i2c_send_byte(u8 byte)
{
    I2C1_SCK_LOW();
    for(u8 i = 0; i < 8; i++)
    {
        if(byte & 0x01)
        {
            I2C1_SDA_HIGH();
        }
        else
        {
            I2C1_SDA_LOW();
        }
            
        byte >>= 1;
        I2C1_SCK_HIGH();
        delay_us(2);
        I2C1_SCK_LOW();
        delay_us(2);
    }
}

static void i2c_stop(void)
{
    I2C1_SCK_LOW();
    I2C1_SDA_LOW();
    delay_us(2);
    I2C1_SCK_HIGH();
    delay_us(2);
    I2C1_SDA_HIGH();
    delay_us(2);
}

static void tm1640_send_data(u8 cmd, u8 addr, u8 data)
{
    i2c_start();
    i2c_send_byte(cmd);
    i2c_stop();
    i2c_start();
    i2c_send_byte(addr);
    i2c_send_byte(data);
    i2c_stop();
}

static void tm1640_send_data_fixed(u8 addr, u8 *buf, u8 len)
{
    i2c_start();
    i2c_send_byte(TM1640_CMD_DATA_FIXED);
    i2c_stop();
    i2c_start();
    while(len--)
    {
        i2c_send_byte(addr);
        i2c_send_byte(*buf++);
    }
    i2c_stop();
}

static void tm1640_send_data_plus(u8 addr, u8 *buf, u8 len)
{
    i2c_start();
    i2c_send_byte(TM1640_CMD_DATA_PLUS);
    i2c_stop();
    i2c_start();
    i2c_send_byte(addr);
    while(len--)
    {
        i2c_send_byte(*buf++);
    }
    i2c_stop();
}

void tm1640_set_luminance(u8 cmd)
{
    i2c_start();
    i2c_send_byte(cmd);
    i2c_stop();
}

/* 此处数据长度写定9字节，后续要记得更改，长度应与len相同 */
void tm1640_set_output(u8 *buf, u8 len)
{
    static u8 __xdata preBuf[9];
    for(u8 __xdata i = 0; i < 9; i++)
    {
        if(preBuf[i] != buf[i])
        {
            preBuf[i] = buf[i];
            tm1640_send_data_plus((u8)tm1640_addr[i], buf + i, 1);
        }
    }
    // tm1640_send_data_plus((u8)tm1640_addr[0], buf, len);
}

static void tm1640_set_full(void)
{
    u8 __xdata buf[9] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

    tm1640_set_output(buf, 9);
}

static void tm1640_set_clear(void)
{
    u8 __xdata buf[9] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    tm1640_set_output(buf, 9);
}

void tm1640_init(void)
{
    i2c_gpio_config();
    tm1640_set_luminance(TM1640_CMD_LIGHT_4_16);
    tm1640_set_full();
    delay_ms(2000);
    tm1640_set_clear();
    delay_ms(500);
}